extends Object

func concatOpcodeArray(array,split_char):
	var ar_str=""
	for i in range(array.size()):
		var value = luaOpcode(array[i])
		if i==array.size()-1:
			ar_str="%s%s" % [ar_str,value]
		else:
			ar_str="%s%s%s" % [ar_str,value,split_char]	
	return ar_str

func isExpression(token):
	if token.get("AddOp") or token.get("SubOp") or token.get("MultOp")  or token.get("FloatDivOp"):
		return true
	else:
		return false
	
func getLeftRightValue(token):
	var left = token.get("left")
	if left:
		var left_str=luaOpcode(left)
		if isExpression(left):
			left="(%s)" % [left_str]
		else:
			left = left_str
	else:
		left=""
	var right = token.get("right")
	if right:
		var right_str = luaOpcode(right)
		if isExpression(right):
			right="(%s)" % [right_str]
		else:
			right=right_str
	else:
		right=""
	return [left,right]
	
func luaOpcode(token):
	for key in token.keys():
		return call("lua"+key,token[key])
		
func luaString(token):
	var value = token.get("s","")
	return '"'+value +'\"'
	
func luaName(token):
	return token["id"]

#连接符..	
func luaConcat(token):
	var left_right = getLeftRightValue(token)
	return "%s..%s" % [left_right[0],left_right[1]]
	
func luaTable(token):
	return "{}"
	
func luaNil(token):
	return "nil"
	
func luaNumber(token):
	return token.get("n",0)
	
func luaTrue(token):
	return "true"
	
func luaFalse(token):
	return "false"
	
func luaIndex(token):
	var property = luaOpcode(token["idx"])
	var object = luaOpcode(token["value"])
	return "%s[%s]" % [object,property]
	
func luaULengthOp(token):
	var operadnd =  luaOpcode(token["operand"])
	#数组长度表达式
	return "#"+operadnd
	
func luaVarargs(token):
	return "..."
	
func luaWhile(token):
	 var body = luaBody(token.get("body"))
	 var expre = luaOpcode(token.get("test"))
	 return "while(%s) do\n%s\nend" % [expre,body]
	
func luaBreak(token):
	  return "break"
	
#分号;	
func luaSemiColon(token):
	 return ""

# 加法	
func luaAddOp(token):
	var left_right = getLeftRightValue(token)
	return "%s+%s" % [left_right[0],left_right[1]]

# 减法	
func luaSubOp(token):
	var left_right = getLeftRightValue(token)
	return "%s-%s" % [left_right[0],left_right[1]]
	
#除法	
func luaFloatDivOp(token):
	var left_right = getLeftRightValue(token)
	return "%s/%s" % [left_right[0],left_right[1]]
#乘法	
func luaMultOp(token):
	var left_right = getLeftRightValue(token)
	return "%s*%s" % [left_right[0],left_right[1]]

#取模	
func luaModOp(token):
	var left_right = getLeftRightValue(token)
	return "%s%%%s" % [left_right[0],left_right[1]]
	
#非运算	
func luaULNotOp(token):
	var operadnd =  luaOpcode(token["operand"])
	return "not " + operadnd

#等于	
func luaREqOp(token):
	var left_right = getLeftRightValue(token)
	return "%s==%s" % [left_right[0],left_right[1]]

#不等于	
func luaRNotEqOp(token):
	var left_right = getLeftRightValue(token)
	return "%s~=%s" % [left_right[0],left_right[1]]

#与		
func luaLAndOp(token):
	var left_right = getLeftRightValue(token)
	return "%s and %s" % [left_right[0],left_right[1]]

#或	
func luaLOrOp(token):
	var left_right = getLeftRightValue(token)
	return "%s or %s" % [left_right[0],left_right[1]]

#大于	
func luaRGtOp(token):
	var left_right = getLeftRightValue(token)
	return "%s > %s" % [left_right[0],left_right[1]]

#大于等于
func luaRGtEqOp(token):
	var left_right = getLeftRightValue(token)
	return "%s >= %s" % [left_right[0],left_right[1]]

#小于	
func luaRLtOp(token):
	var left_right = getLeftRightValue(token)
	return "%s < %s" % [left_right[0],left_right[1]]

#小于等于
func luaRLtEqOp(token):
	var left_right = getLeftRightValue(token)
	return "%s <= %s" % [left_right[0],left_right[1]]
	
func luaUMinusOp(token):
	var operand = token.get("operand",{})
	return -luaNumber(operand.get("Number",{}))

#操作块 test() 
func luaCall(token):
	var func_name = luaOpcode(token["func"])
	var args=concatOpcodeArray(token.get("args",[]),",")
	return "%s(%s)" % [func_name,args]
	
#local a=b
func luaLocalAssign(value):
	var targets =  value["targets"]
	var values = value.get("values",[])
	var code="%s%s=%s" % ["local ",concatOpcodeArray(targets,","),concatOpcodeArray(values,",")]
	return code
	
func luaAssign(value):
	var targets =  value["targets"]
	var values = value.get("values",[])
	var code="%s=%s" % [concatOpcodeArray(targets,","),concatOpcodeArray(values,",")]
	return code
		
func luaBody(body):
	var code = ""
	if body:
		if typeof(body) == TYPE_ARRAY:
			for value in body:
				for key in value.keys():
					#print(key,":\n",value[key])
					code = "%s%s\n" % [code,call("lua"+key,value[key])]
		else:
			#body 里面有block ,block 里面还会有body
			if body.get("Block") and body.get("Block").get("body"):
				code = luaBody(body.get("Block").get("body"))
			else:
				print("error:\n",body)
	return code
	
func luaIf(value):
	var test =  luaOpcode(value["test"])
	var body = luaBody(value.get("body"))
	var result = "if %s then\n%send\n" % [test,body]
	return result
	

func luaInvoke(value):
	var args=  concatOpcodeArray(value.get("args",[]),",")
	var func_name = luaOpcode(value["func"])
	var source = value.get("source")
	var soure_str = luaOpcode(source)
	if len(soure_str)>0:
		soure_str=soure_str+"."
	var invoke = "%s%s(%s)" % [soure_str,func_name,args]
	return invoke
	
	
func luaForin(value):
	var body = luaBody(value.get("body"))
	var iter = luaOpcode(value["iter"][0])
	var targets = concatOpcodeArray(value.get("targets"),",")
	return "for %s in %s do\n%s\nend"  % [targets,iter,body]

func luaFornum(value):
	#print("Fornum\n",JSON.print(value))
	var step  = luaOpcode(value["target"])
	var begin =luaOpcode(value["start"])
	var stop = luaOpcode(value["stop"])
	var body = luaBody(value.get("body"))
	return "for %s=%s,%s do\n%s\nend\n" % [step,begin,stop,body]

func luaReturn(value):
	var values=value.get("values",[])
	var return_value = concatOpcodeArray(values,",")
	return "return " + return_value

#对象方法	 lua中的:
func luaMethod(value):
	var func_name = luaOpcode(value["name"])
	var soure_str = luaOpcode(value.get("source"))
	var body = luaBody(value.get("body"))
	var args = concatOpcodeArray(value.get("args",[]),",")
	return "function %s:%s(%s)\n%s\nend\n" % [soure_str,func_name,args,body]

func luaFunction(value):
	var names = value["name"]
	var func_fix=""
	var Index = names.get("Index")
	if Index:
		var property = luaOpcode(Index["idx"])
		var object = luaOpcode(Index["value"])
		names="%s[%s]" % [object,property]
		
	var args = concatOpcodeArray(value.get("args",[]),",")
	var body = luaBody(value.get("body"))
	var luafunc = "%s=function(%s)\n %s\nend\n" % [names,args,body]
	return luafunc
	
#匿名函数写法 local a =function() end	
func luaAnonymousFunction(value):
	var func_body = luaBody(value.get("body"))
	var parmter = concatOpcodeArray(value.get("args",[]),",")
	return "function(%s)\n%s\nend" % [parmter,func_body]	
	
func luaLocalFunction(value):
	var names = luaOpcode(value["name"])
	var args = concatOpcodeArray(value.get("args",[]),",")
	var body = luaBody(value.get("body"))
	var luafunc = "local function %s(%s)\n %s\nend\n" % [names,args,body]
	return luafunc

